using System;
using System.Windows;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
using RotovapPlatform.UI.Views;
using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore;
using RotovapPlatform.Infrastructure.Common.Data;
using RotovapPlatform.UI.ViewModels.Navigation;
using RotovapPlatform.Infrastructure.Common.Data.Seeds;
using RotovapPlatform.UI.ViewModels.RecipeManagement;
using RotovapPlatform.Application.DependencyInjection;
using RotovapPlatform.Infrastructure.DependencyInjection;
using RotovapPlatform.UI.ViewModels.MaterialManagement;
using RotovapPlatform.UI.Views.MaterialManagement;

using System.IO;
using RotovapPlatform.UI.Views.Navigation;
using RotovapPlatform.UI.ViewModels.ExperimentManagement;
using RotovapPlatform.UI.Views.ExperimentManagement;
using RotovapPlatform.UI.Views.RecipeManagement;
using RotovapPlatform.Application.Services.Devices;
using RotovapPlatform.UI.ViewModels.DataRecord;
using RotovapPlatform.UI.ViewModels.DeviceMaintenance;
using RotovapPlatform.UI.ViewModels.DeviceMaintenance.ManualOperation;
using RotovapPlatform.UI.ViewModels.User;
using RotovapPlatform.UI.Views.DataRecord;
using RotovapPlatform.UI.Views.DeviceMaintenance;
using RotovapPlatform.UI.Views.User;
using System.Collections.Generic;
using RotovapPlatform.Domain.Equipment.Interfaces.Base;
using RotovapPlatform.UI.Views.DeviceMaintenance.ManualOperation;
using RotovapPlatform.Domain.Equipment.Interfaces.Services;
using RotovapPlatform.Domain.Services.Data;
using RotovapPlatform.Domain.Services.Scheduling;

namespace RotovapPlatform.UI;

public partial class App : System.Windows.Application
{
	private ServiceProvider _serviceProvider;

	public static ServiceProvider ServiceProvider { get; private set; }

	public App()
	{
		var services = new ServiceCollection();
		ConfigureServices(services);
		ServiceProvider = services.BuildServiceProvider();
		_serviceProvider = ServiceProvider;
	}

	private void ConfigureServices(IServiceCollection services)
	{
		// 配置日志
		services.AddLogging(builder =>
		{
			builder.AddDebug();
			builder.AddConsole();

			// 配置日志过滤
			builder.AddFilter("RotovapPlatform.Infrastructure.Equipment.Devices.IO.IOModuleService", LogLevel.Information);
		});



		// 注册主窗口
		services.AddTransient<MainWindow>();

		// 统一数据库路径配置
		var solutionDir = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\..\\..\\.."));
		var dbPath = Path.Combine(solutionDir, "src", "RotovapPlatform.Infrastructure", "Data", "Rotovap.db");

		// 确保数据库目录存在
		var dbFolder = Path.GetDirectoryName(dbPath);
		if (!Directory.Exists(dbFolder))
		{
			Directory.CreateDirectory(dbFolder);
		}

		// 添加DbContext   
		services.AddDbContext<RecipeDbContext>(options =>
			options.UseSqlite($"Data Source={dbPath}"));

		// 添加 StorageDbContext
		services.AddDbContext<StorageDbContext>(options =>
			options.UseSqlite($"Data Source={dbPath}"));

		//添加ExperimentGroupDbContext
		services.AddDbContext<ExperimentGroupDbContext>(options =>
			options.UseSqlite($"Data Source={dbPath}"));

		//添加ExperimentDbContext
		services.AddDbContext<ExperimentDbContext>(options =>
			options.UseSqlite($"Data Source={dbPath}"));

		// 注册导航相关服务
		services.AddSingleton<NavigationViewModel>();
		services.AddTransient<SideMenuView>();

		// 注册所有视图和视图模型

		// 实验管理
		services.AddSingleton<MainOperationViewModel>();
		services.AddTransient<MainOperationView>();
		services.AddTransient<HistoryExperimentView>();
		services.AddTransient<HistoryExperimentViewModel>();
		services.AddTransient<RealTimeDataView>();
		services.AddTransient<RealTimeDataViewModel>();

		// 配方管理
		services.AddTransient<RecipeEditorView>();
		services.AddTransient<RecipeEditorViewModel>();
		services.AddTransient<HistoryExperimentGroupView>();
		services.AddTransient<HistoryExperimentGroupViewModel>();

		// 物料管理
		services.AddTransient<MaterialManagementView>();
		services.AddSingleton<ShelfViewModel>();
		services.AddTransient<StockInOutView>();
		services.AddTransient<StockInOutViewModel>();
		services.AddTransient<StockInOutRecordView>();
		services.AddTransient<StockInOutRecordViewModel>();
		services.AddTransient<MaterialQueryView>();
		services.AddTransient<MaterialQueryViewModel>();

		// 数据记录
		services.AddTransient<DeviceAlarmRecordView>();
		services.AddTransient<DeviceAlarmRecordViewModel>();
		services.AddTransient<OperationLogView>();
		services.AddTransient<OperationLogViewModel>();
		services.AddTransient<HistoryProcessDataView>();
		services.AddTransient<HistoryProcessDataViewModel>();

		//设备维护	
		services.AddTransient<DeviceMaintenanceView>();
		services.AddTransient<DeviceMaintenanceViewModel>();
		services.AddTransient<ManualOperationView>();
		services.AddTransient<ManualOperationViewModel>();
		services.AddTransient<ManualIOViewModel>();
		services.AddTransient<ManualIOView>();
		services.AddTransient<MotorControlViewModel>();
		services.AddTransient<MotorControlView>();
		services.AddTransient<RobotControlViewModel>();
		services.AddTransient<RobotControlView>();
		services.AddTransient<SerialDevicesListViewModel>();
		services.AddTransient<SerialDevicesListView>();
		services.AddTransient<SerialDevicesListViewModel>();
		services.AddTransient<SerialDevicesListView>();
		services.AddTransient<DeviceParameterView>();
		services.AddTransient<DeviceParameterViewModel>();
		services.AddTransient<MaintenanceReminderView>();
		services.AddTransient<MaintenanceReminderViewModel>();

		//登录
		services.AddTransient<LoginView>();
		services.AddTransient<LoginViewModel>();


		// 注册对话框服务
		services.AddSingleton<IMessageService, MessageService>();



		// 注册应用层服务
		services.AddApplicationServices();

		// 注册基础设施层服务
		services.AddInfrastructureServices();

		// 添加调试日志
		Console.WriteLine("==========================================================");
		Console.WriteLine("基础设施层服务已注册，请查找 RegisterMotorsFromDeviceParameters 方法输出");
		Console.WriteLine("==========================================================");
	}

	protected override async void OnStartup(StartupEventArgs e)
	{
		base.OnStartup(e);

		// 确保配置目录存在
		var configDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config");
		if (!Directory.Exists(configDir))
		{
			Directory.CreateDirectory(configDir);
		}

		// 检查并复制默认配置文件
		CopyDefaultConfigFiles();

		// 初始化数据库
		using (var scope = ServiceProvider.CreateScope())
		{
			var services = scope.ServiceProvider;
			var logger = services.GetRequiredService<ILogger<App>>();

			try
			{
				logger.LogInformation("开始初始化数据库...");

				// 数据库重建选项
				// 注意：设置为true将删除并重建相应的数据库，所有数据将丢失
				// 仅在需要重建数据库结构时才设置为true
				bool rebuildRecipeDb = false;
				bool rebuildStorageDb = false;
				bool rebuildExperimentGroupDb = false;

				logger.LogInformation("配方数据库重建选项: {RebuildRecipeDb}", rebuildRecipeDb);
				logger.LogInformation("存储数据库重建选项: {RebuildStorageDb}", rebuildStorageDb);
				logger.LogInformation("实验组数据库重建选项: {RebuildExperimentGroupDb}", rebuildExperimentGroupDb);

				// 初始化配方数据库
				logger.LogInformation("开始初始化配方数据库...");
				var recipeContext = services.GetRequiredService<RecipeDbContext>();

				if (rebuildRecipeDb)
				{
					logger.LogWarning("正在删除配方数据库...");
					await recipeContext.Database.EnsureDeletedAsync();
					logger.LogWarning("配方数据库已删除");
				}

				logger.LogInformation("正在创建配方数据库...");
				await recipeContext.Database.EnsureCreatedAsync();
				logger.LogInformation("配方数据库创建完成");

				// 如果是新数据库或者重建了数据库，则需要重新填充种子数据
				if (rebuildRecipeDb || !(await recipeContext.Recipes.AnyAsync()))
				{
					logger.LogInformation("正在填充配方数据库种子数据...");
					await RecipeSeed.SeedAsync(recipeContext);
					logger.LogInformation("配方数据库种子数据填充完成");
				}

				// 初始化存储数据库
				logger.LogInformation("开始初始化存储数据库...");
				var storageContext = services.GetRequiredService<StorageDbContext>();

				if (rebuildStorageDb)
				{
					logger.LogWarning("正在删除存储数据库...");
					await storageContext.Database.EnsureDeletedAsync();
					logger.LogWarning("存储数据库已删除");
				}

				logger.LogInformation("正在创建存储数据库...");
				await storageContext.Database.EnsureCreatedAsync();
				logger.LogInformation("存储数据库创建完成");

				// 如果是新数据库或者重建了数据库，则需要重新填充种子数据
				if (rebuildStorageDb || !(await storageContext.StorageLocations.AnyAsync()))
				{
					logger.LogInformation("正在填充存储数据库种子数据...");
					await StorageLocationSeed.SeedAsync(storageContext);
					logger.LogInformation("存储数据库种子数据填充完成");
				}

				// 初始化实验组数据库
				logger.LogInformation("开始初始化实验组数据库...");
				var experimentGroupContext = services.GetRequiredService<ExperimentGroupDbContext>();

				if (rebuildExperimentGroupDb)
				{
					logger.LogWarning("正在删除实验组数据库...");
					await experimentGroupContext.Database.EnsureDeletedAsync();
					logger.LogWarning("实验组数据库已删除");
				}

				logger.LogInformation("正在创建实验组数据库...");
				await experimentGroupContext.Database.EnsureCreatedAsync();
				logger.LogInformation("实验组数据库创建完成");

				logger.LogInformation("所有数据库初始化完成");

				// 检查默认配置文件
				try
				{
					Console.WriteLine("==========================================================");
					var configDirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config");
					var defaultConfigPath = Path.Combine(configDirPath, "defaultDeviceParameters.json");
					var deviceParamsPath = Path.Combine(configDirPath, "deviceParameters.json");

					Console.WriteLine($"检查配置文件目录: {configDirPath}");
					Console.WriteLine($"目录是否存在: {Directory.Exists(configDirPath)}");

					Console.WriteLine($"检查默认配置文件: {defaultConfigPath}");
					Console.WriteLine($"文件是否存在: {File.Exists(defaultConfigPath)}");
					if (File.Exists(defaultConfigPath))
					{
						long fileSize = new FileInfo(defaultConfigPath).Length;
						Console.WriteLine($"文件大小: {fileSize} 字节");

						if (fileSize > 0)
						{
							// 读取文件前100个字符
							string content = File.ReadAllText(defaultConfigPath);
							string preview = content.Length > 100 ? content.Substring(0, 100) + "..." : content;
							Console.WriteLine($"文件内容预览: {preview}");
						}
					}

					Console.WriteLine($"检查设备参数文件: {deviceParamsPath}");
					Console.WriteLine($"文件是否存在: {File.Exists(deviceParamsPath)}");
					Console.WriteLine("==========================================================");

					// 检查设备参数服务
					try
					{
						Console.WriteLine("尝试获取 IDeviceParameterService 实例");
						var deviceParamService = services.GetRequiredService<RotovapPlatform.Domain.Equipment.DeviceParameters.IDeviceParameterService>();
						Console.WriteLine($"成功获取 IDeviceParameterService 实例: {deviceParamService != null}");

						// 尝试获取参数
						Console.WriteLine("调用 IDeviceParameterService.GetParametersAsync() 方法");
						var parameters = await deviceParamService.GetParametersAsync();
						Console.WriteLine($"获取到参数: {parameters != null}");

						if (parameters != null)
						{
							Console.WriteLine($"设备信息: {parameters.DeviceInfo?.Name ?? "未设置"}");
							Console.WriteLine($"电机数量: {parameters.Motors?.Count ?? 0}");

							if (parameters.Motors != null && parameters.Motors.Count > 0)
							{
								foreach (var motor in parameters.Motors)
								{
									Console.WriteLine($"- 电机: ID={motor.Id}, 名称={motor.Name}, 轴号={motor.AxisId}");
								}
							}
						}
					}
					catch (Exception ex)
					{
						Console.WriteLine($"获取或访问 IDeviceParameterService 时出错: {ex.Message}");
						Console.WriteLine($"异常堆栈: {ex.StackTrace}");
					}
				}
				catch (Exception ex)
				{
					Console.WriteLine($"检查配置文件时出错: {ex.Message}");
					Console.WriteLine($"异常堆栈: {ex.StackTrace}");
				}

				// 尝试初始化电机控制服务
				try
				{
					Console.WriteLine("==========================================================");
					Console.WriteLine("尝试获取 IMotorControlService 实例");
					var motorControlService = services.GetRequiredService<RotovapPlatform.Domain.Equipment.Interfaces.Services.IMotorControlService>();
					Console.WriteLine($"成功获取 IMotorControlService 实例: {motorControlService != null}");

					// 直接初始化电机控制服务，不再使用Lazy<Task<List<IMotorBase>>>
					try
					{
						// 直接调用初始化方法
						Console.WriteLine("直接调用 IMotorControlService.InitializeAsync() 方法");
						var initResult = await motorControlService.InitializeAsync();
						Console.WriteLine($"IMotorControlService.InitializeAsync() 结果: {initResult}");

						// 获取注册的电机列表
						Console.WriteLine("获取已注册的电机列表");
						var motors = await motorControlService.GetRegisteredMotorsAsync();
						if (motors != null && motors.Count > 0)
						{
							Console.WriteLine($"成功获取到 {motors.Count} 个已注册电机");
							foreach (var motor in motors)
							{
								Console.WriteLine($"电机信息: ID={motor.AxisNo}, Name={motor.Name}");
							}
						}
						else
						{
							Console.WriteLine("警告: 未能获取到已注册电机，或电机列表为空");
						}
					}
					catch (Exception ex)
					{
						Console.WriteLine($"初始化电机控制服务或获取电机列表时出错: {ex.Message}");
						Console.WriteLine($"异常堆栈: {ex.StackTrace}");
					}
					Console.WriteLine("==========================================================");
				}
				catch (Exception ex)
				{
					Console.WriteLine($"获取或初始化 IMotorControlService 时出错: {ex.Message}");
					Console.WriteLine($"异常堆栈: {ex.StackTrace}");
				}
			}
			catch (Exception ex)
			{
				logger.LogError(ex, "数据库初始化过程中发生错误");
				MessageBox.Show($"初始化数据库时发生错误: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
			}
		}

		//// 初始化设备服务
		var deviceManager = ServiceProvider.GetRequiredService<IDeviceManager>();
		var statusService = ServiceProvider.GetRequiredService<IDeviceStatusService>();
		await deviceManager.InitializeAsync();
		await statusService.StartMonitoringAsync();

		// 初始化数据记录服务与任务调度服务的事件订阅关系
		InitializeDataRecordingEventSubscriptions(ServiceProvider);

		// 启动设备状态监控
		_ = InitializeDeviceMonitoringAsync(ServiceProvider);

		// 初始化实验流程协调器
		_ = InitializeExperimentCoordinatorAsync(ServiceProvider);

		// 创建和显示主窗口
		var mainWindow = ServiceProvider.GetRequiredService<MainWindow>();
		mainWindow.Show();
	}

	/// <summary>
	/// 初始化设备状态监控
	/// </summary>
	private async Task InitializeDeviceMonitoringAsync(IServiceProvider serviceProvider)
	{
		try
		{
			var deviceAppService = serviceProvider.GetRequiredService<IDeviceAppService>();
			await deviceAppService.StartMonitoringAsync();
		}
		catch (Exception ex)
		{
			var logger = serviceProvider.GetRequiredService<ILogger<App>>();
			logger.LogError(ex, "初始化设备状态监控时发生错误");
		}
	}

	/// <summary>
	/// 初始化实验流程协调器
	/// </summary>
	private async Task InitializeExperimentCoordinatorAsync(IServiceProvider serviceProvider)
	{
		try
		{
			var experimentProcessCoordinator = serviceProvider.GetRequiredService<RotovapPlatform.Application.Services.Experiments.IExperimentProcessCoordinator>();
			experimentProcessCoordinator.Initialize();
			Console.WriteLine("实验流程协调器初始化成功");
		}
		catch (Exception ex)
		{
			var logger = serviceProvider.GetRequiredService<ILogger<App>>();
			logger.LogError(ex, "初始化实验流程协调器时发生错误");
			Console.WriteLine($"初始化实验流程协调器时出错: {ex.Message}");
		}
	}

	/// <summary>
	/// 复制默认配置文件
	/// </summary>
	private void CopyDefaultConfigFiles()
	{
		try
		{
			Console.WriteLine("==========================================================");
			Console.WriteLine("开始复制默认配置文件");

			// 确保配置目录存在
			var baseDir = AppDomain.CurrentDomain.BaseDirectory;
			var configDir = Path.Combine(baseDir, "Config");
			if (!Directory.Exists(configDir))
			{
				Directory.CreateDirectory(configDir);
				Console.WriteLine($"创建配置目录: {configDir}");
			}

			// 源文件路径
			var solutionDir = Path.GetFullPath(Path.Combine(baseDir, "..\\..\\..\\..\\.."));
			var sourceDefaultConfigPath = Path.Combine(solutionDir, "src", "RotovapPlatform.Infrastructure", "Config", "defaultDeviceParameters.json");

			// 目标文件路径
			var destDefaultConfigPath = Path.Combine(configDir, "defaultDeviceParameters.json");

			Console.WriteLine($"源默认配置文件路径: {sourceDefaultConfigPath}");
			Console.WriteLine($"源文件是否存在: {File.Exists(sourceDefaultConfigPath)}");
			Console.WriteLine($"目标默认配置文件路径: {destDefaultConfigPath}");
			Console.WriteLine($"目标文件是否存在: {File.Exists(destDefaultConfigPath)}");

			// 如果源文件存在且目标文件不存在，复制文件
			if (File.Exists(sourceDefaultConfigPath) && !File.Exists(destDefaultConfigPath))
			{
				Console.WriteLine("正在复制默认配置文件...");
				File.Copy(sourceDefaultConfigPath, destDefaultConfigPath);
				Console.WriteLine("默认配置文件复制完成");
			}
			else if (!File.Exists(sourceDefaultConfigPath))
			{
				Console.WriteLine("源默认配置文件不存在，无法复制");
			}
			else if (File.Exists(destDefaultConfigPath))
			{
				Console.WriteLine("目标默认配置文件已存在，不进行复制");
			}

			Console.WriteLine("==========================================================");
		}
		catch (Exception ex)
		{
			Console.WriteLine($"复制默认配置文件时出错: {ex.Message}");
			Console.WriteLine($"异常堆栈: {ex.StackTrace}");
		}
	}

	/// <summary>
	/// 初始化数据记录服务与任务调度服务的事件订阅关系
	/// </summary>
	private void InitializeDataRecordingEventSubscriptions(IServiceProvider serviceProvider)
	{
		try
		{
			// 创建服务范围
			using (var scope = serviceProvider.CreateScope())
			{
				var services = scope.ServiceProvider;
				var logger = services.GetRequiredService<ILogger<App>>();

				logger.LogInformation("开始初始化数据记录服务与任务调度服务的事件订阅关系");

				// 获取数据记录服务和任务调度服务
				var dataRecordingService = services.GetRequiredService<IDataRecordingDomainService>();
				var taskSchedulingService = services.GetRequiredService<ITaskSchedulingDomainService>();

				// 建立事件订阅关系
				dataRecordingService.SubscribeToTaskSchedulingEvents(taskSchedulingService);

				logger.LogInformation("数据记录服务成功订阅任务调度服务的事件");
			}
		}
		catch (Exception ex)
		{
			// 在这里我们不能使用logger，因为它可能在CreateScope内部
			Console.WriteLine($"初始化数据记录服务事件订阅时出错: {ex.Message}");
			Console.WriteLine($"异常堆栈: {ex.StackTrace}");
		}
	}

	protected override void OnExit(ExitEventArgs e)
	{
		try
		{
			// 释放实验流程协调器资源
			var experimentProcessCoordinator = _serviceProvider.GetService<RotovapPlatform.Application.Services.Experiments.IExperimentProcessCoordinator>();
			if (experimentProcessCoordinator != null)
			{
				experimentProcessCoordinator.Dispose();
				Console.WriteLine("实验流程协调器资源已释放");
			}
		}
		catch (Exception ex)
		{
			Console.WriteLine($"释放实验流程协调器资源时出错: {ex.Message}");
		}

		base.OnExit(e);
		_serviceProvider.Dispose();
	}

	public T GetService<T>() where T : class
	{
		return _serviceProvider.GetService<T>();
	}
}